import { BeforeOpenModalResult, ElementPropertyConfig } from '@farris/ide-property-panel';
import { CodeEditorComponent, CollectionWithPropertyConverter, CollectionWithPropertyEditorComponent } from '@farris/designer-devkit';
import { FormPropertyChangeObject } from '../../../../../lib/entity/property-change-entity';
import { InputProps } from '../../common/property/input-property-config';
import { DgControl } from '../../../../utils/dg-control';
import { ImportCmpComponent, ImportCmpConverter, MappingConverter, SelectMappingComponent } from '@farris/designer-devkit';
import { ToolBarItemProp } from '../../../command/toolbar/component/toolbaritem/property/property-config';
import { EventsEditorFuncUtils } from '../../../../utils/events-editor-func';

export class InputGroupProp extends InputProps {


    propertyConfig: ElementPropertyConfig[];

    getPropConfig(propertyData: any): ElementPropertyConfig[] {
        let propertyConfig: ElementPropertyConfig[] = [];

        // 弹出表单框属性
        const openModalPropConfigs = this.getOpenModalPropConfigs(propertyData, this.viewModelId);

        // 基本信息属性
        const basicPropConfig = this.getBasicPropConfig(propertyData, this.viewModelId);
        propertyConfig.push(basicPropConfig);

        // 外观属性
        const appearanceProperties = this.getAppearancePropConfig(propertyData, this.viewModelId, openModalPropConfigs);
        propertyConfig.push(appearanceProperties);

        // 行为属性
        const behaviorPropConfig = this.getBehaviorPropConfig(propertyData, this.viewModelId, openModalPropConfigs);
        propertyConfig.push(behaviorPropConfig);
        propertyConfig = propertyConfig.concat(openModalPropConfigs);

        // 扩展区域属性
        // const appendPropConfig = this.getInputAppendPropertyConfig(propertyData, this.viewModelId);
        // propertyConfig.push(appendPropConfig);

        // 事件属性
        const eventPropConfig = this.getEventPropConfig(propertyData, this.viewModelId);
        propertyConfig.push(eventPropConfig);

        // 表达式属性
        const exprPropConfig = this.getExpressionPropConfig(propertyData, this.viewModelId);
        if (exprPropConfig) {
            propertyConfig.push(exprPropConfig);
        }

        return propertyConfig;
    }


    /**
     * 外观属性
     */
    getAppearancePropConfig(
        propertyData: any, viewModelId: string, openModalPropConfigs: ElementPropertyConfig[], showPosition = 'card'):
        ElementPropertyConfig {
        const self = this;
        let appearanceProperties = [];
        if (showPosition === 'card' || showPosition === 'tableTdEditor') {
            appearanceProperties = this.getAppearanceCommonPropConfig(propertyData, viewModelId, showPosition);
        }

        appearanceProperties.push(
            {
                propertyID: 'textAlign',
                propertyName: '数据水平对齐方式',
                propertyType: 'select',
                description: '数据水平对齐方式设置',
                iterator: [{ key: 'left', value: '靠左' }, { key: 'right', value: '靠右' }, { key: 'center', value: '居中' }]
            }
        );
        const config = {
            categoryId: 'appearance',
            categoryName: '外观',
            properties: appearanceProperties,
            setPropertyRelates(changeObject: FormPropertyChangeObject, prop, parameters) {

                if (!changeObject) {
                    return;
                }
                self.changeAppearancePropertyRelates(this.properties, changeObject, propertyData, parameters);
            }

        };
        if (showPosition !== 'card') {
            Object.assign(config, {
                categoryId: showPosition + '_' + config.categoryId,
                propertyData,
                enableCascade: true,
                parentPropertyID: 'editor',
                tabId: showPosition,
                tabName: '编辑器'
            });
        }
        return config;
    }

    /**
     * 行为属性
     */
    getBehaviorPropConfig(
        propertyData: any, viewModelId: string, openModalPropConfigs: ElementPropertyConfig[], showPosition = 'card'):
        ElementPropertyConfig {

        const self = this;
        let behaviorProperties = [];
        if (showPosition === 'card' || showPosition === 'tableTdEditor') {
            behaviorProperties = this.getBehaviorCommonPropConfig(propertyData, viewModelId);
        }
        behaviorProperties.push(
            {
                propertyID: 'editable',
                propertyName: '允许输入',
                propertyType: 'boolean',
                description: '是否允许输入',
            },
            {
                propertyID: 'groupText',
                propertyName: '按钮显示文本',
                propertyType: 'modal',
                description: '按钮显示文本设置',
                editor: CodeEditorComponent,
                editorParams: {
                    language: 'html'
                },
            },
            {
                propertyID: 'showButtonWhenDisabled',
                propertyName: '禁用时显示按钮',
                propertyType: 'boolean',
                description: '禁用时是否显示按钮'
            },
            {
                propertyID: 'isPassword',
                propertyName: '密码输入框',
                propertyType: 'boolean',
                description: '是否为密码输入框',
                defaultValue: false
            },
            {
                propertyID: 'enableViewPassword',
                propertyName: '允许查看密码',
                propertyType: 'boolean',
                description: '是否允许查看密码',
                defaultValue: false,
                visible: propertyData.isPassword
            },
            {
                propertyID: 'usageMode',
                propertyName: '使用模式',
                propertyType: 'select',
                description: '使用模式选择',
                detail: "https://igix.inspures.com/igixword/main.html#inputgroup",
                iterator: [
                    { key: 'text', value: '文本' },
                    { key: 'open-modal', value: '弹出表单' },
                    { key: 'open-remote-modal', value: '弹出远端表单' }
                ],
                refreshPanelAfterChanged: true
            },
            {
                propertyID: 'enableClear',
                propertyName: '启用清除按钮',
                propertyType: 'boolean'
            }
        );

        const config = {
            categoryId: 'behavior',
            categoryName: '行为',
            properties: behaviorProperties,
            setPropertyRelates(changeObject: FormPropertyChangeObject, prop, parameters) {

                if (!changeObject) {
                    return;
                }
                self.changeBehaviorPropertyRelates(this.properties, changeObject, propertyData, parameters, showPosition);

                switch (changeObject.propertyID) {
                    case 'isPassword': {
                        const enableViewPassword = this.properties.find(p => p.propertyID === 'enableViewPassword');
                        if (enableViewPassword) {
                            enableViewPassword.visible = changeObject.propertyValue;
                            propertyData.enableViewPassword = changeObject.propertyValue ? propertyData.enableViewPassword : false;
                        }
                        changeObject.relateChangeProps = [{
                            propertyID: 'enableViewPassword',
                            propertyValue: propertyData.enableViewPassword
                        }];
                        break;
                    }
                    case 'usageMode': {
                        if (openModalPropConfigs && openModalPropConfigs.length) {
                            openModalPropConfigs.forEach(c => {
                                if (c.categoryId === 'openModal') {
                                    c.hide = propertyData.usageMode !== 'open-modal';
                                } else {
                                    c.hide = propertyData.usageMode === 'text';
                                }
                            });
                        }
                        break;
                    }
                }
            }
        };

        if (showPosition !== 'card') {
            Object.assign(config, {
                categoryId: showPosition + '_' + config.categoryId,
                propertyData,
                enableCascade: true,
                parentPropertyID: 'editor',
                tabId: showPosition,
                tabName: '编辑器'
            });
        }
        return config;

    }

    /**
     * 事件属性
     */
    getEventPropConfig(propertyData: any, viewModelId: string, showPosition = 'card'): ElementPropertyConfig {
        const eventList = [
            {
                label: 'click',
                name: '点击事件'
            },
            {
                label: 'onBlur',
                name: '失去焦点事件'
            },
            {
                label: 'onClear',
                name: '清除事件'
            }
        ];

        return this.getEventPropertyConfig(propertyData, viewModelId, showPosition, { customEventList: eventList });

    }

    /**
     * 动态事件
     * @param propertyData 属性值
     * @param eventList  已有事件
     */
    switchEvents(propertyData, eventList) {
        eventList = super.switchEvents(propertyData, eventList);

        if (propertyData.enableClear) {
            const onClear = eventList.find(eventListItem => eventListItem.label === 'onClear');
            if (!onClear) {
                eventList.push({
                    label: 'onClear',
                    name: '清除事件'
                });
            }
        } else {
            eventList = eventList.filter(eventListItem => eventListItem.label !== 'onClear');
        }

        return eventList;
    }
    /**
     * 弹出表单配置属性
     */
    getOpenModalPropConfigs(propertyData: any, viewModelId: string, showPosition = 'card'): ElementPropertyConfig[] {


        const toolbarItemProp = new ToolBarItemProp(this.injector, this.viewModelId);

        const self = this;
        return [{
            categoryId: 'openModal',
            categoryName: '表单配置',
            hide: propertyData.usageMode !== 'open-modal',
            propertyData: propertyData.modalConfig,
            enableCascade: true,
            parentPropertyID: showPosition !== 'card' ? 'editor.modalConfig' : 'modalConfig',
            tabId: showPosition !== 'card' ? showPosition : null,
            tabName: showPosition !== 'card' ? '编辑器' : null,
            properties: [
                {
                    propertyID: 'modalCmp',
                    propertyName: '弹出表单',
                    propertyType: 'modal',
                    description: '弹出表单元数据窗口',
                    editor: ImportCmpComponent,
                    converter: new ImportCmpConverter(),
                    editorParams: { containerType: DgControl.ModalContainer.type, containerId: propertyData.id, relativePath: this.formBasicService.formMetaBasicInfo.relativePath, name: this.formBasicService.formMetaBasicInfo.name },
                    showClearButton: true,
                    afterClickClearButton(oldValue: string) {
                        self.domService.deleteExternalComponent(oldValue); // 清空外部组件的声明节点
                    }
                },
                {
                    propertyID: 'mapFields',
                    propertyName: '字段映射',
                    propertyType: 'modal',
                    description: '表单映射编辑',
                    editor: SelectMappingComponent,
                    editorParams: {
                        sourceMetadataId: propertyData.modalConfig.formId,
                        viewModelId,
                        binding: propertyData.binding,
                        sourceMetadataType: 'form',
                        sourceMetadataName: '弹出表单'
                    },
                    converter: new MappingConverter(),
                    beforeOpenModal(): BeforeOpenModalResult {
                        if (!propertyData.binding) {
                            return { result: false, message: '请先选择绑定！' };
                        }
                        if (!propertyData.modalConfig || !propertyData.modalConfig.formId) {
                            return { result: false, message: '请先选择弹出表单！' };
                        }
                        // 取弹出表单和绑定的最新值
                        this.editorParams.sourceMetadataId = propertyData.modalConfig.formId;
                        this.editorParams.binding = propertyData.binding;
                        return { result: true, message: '' };
                    }
                }

            ],
            setPropertyRelates(changeObject, propData, parameters) {
                if (!changeObject) {
                    return;
                }
                switch (changeObject.propertyID) {
                    case 'modalCmp': {
                        propData.component = parameters ? parameters.component : '';
                        propData.formId = parameters ? parameters.uri : '';
                        propData.mapFields = '';
                        break;
                    }
                }
            }
        },
        {
            categoryId: 'modalConfig',
            categoryName: '弹出窗口配置',
            hide: propertyData.usageMode === 'text',
            propertyData: propertyData.modalConfig,
            enableCascade: true,
            parentPropertyID: showPosition !== 'card' ? 'editor.modalConfig' : 'modalConfig',
            tabId: showPosition !== 'card' ? showPosition : null,
            tabName: showPosition === 'gridFieldEditor' ? '编辑器' : null,
            properties: [
                {
                    propertyID: 'showHeader',
                    propertyName: '显示标题栏',
                    propertyType: 'boolean',
                    description: '弹出窗口是否显示标题栏'
                },
                {
                    propertyID: 'title',
                    propertyName: '标题',
                    propertyType: 'string',
                    description: '弹出窗口标题',
                    visible: propertyData.modalConfig && propertyData.modalConfig.showHeader,
                    category: 'header'
                },
                {
                    propertyID: 'showCloseButton',
                    propertyName: '显示关闭按钮',
                    propertyType: 'boolean',
                    description: '弹出窗口是否显示关闭按钮',
                    visible: propertyData.modalConfig && propertyData.modalConfig.showHeader,
                    category: 'header'
                },
                {
                    propertyID: 'showMaxButton',
                    propertyName: '显示最大化按钮',
                    propertyType: 'boolean',
                    description: '弹出窗口是否显示最大化按钮',
                    visible: propertyData.modalConfig && propertyData.modalConfig.showHeader,
                    category: 'header'
                },
                {
                    propertyID: 'width',
                    propertyName: '宽度',
                    propertyType: 'number',
                    description: '弹出窗口宽度',
                    min: 0
                },
                {
                    propertyID: 'height',
                    propertyName: '高度',
                    propertyType: 'number',
                    description: '弹出窗口高度',
                    min: 0
                },
                {
                    propertyID: 'showFooterButtons',
                    propertyName: '显示底部按钮区',
                    propertyType: 'boolean',
                    description: '弹出窗口是否显示底部按钮区'
                },
                {
                    propertyID: 'footerButtons',
                    propertyName: '按钮组',
                    propertyType: 'modal',
                    description: '弹出窗口按钮区维护',
                    editor: CollectionWithPropertyEditorComponent,
                    converter: new CollectionWithPropertyConverter(),
                    editorParams: {
                        modalTitle: '工具栏编辑器',
                        viewModelId,
                        idKey: 'id',
                        textKey: 'text',
                        maxCascadeLevel: 1,
                        controlType: DgControl.ToolBarItem.type,
                        defaultControlValue: {
                            id: 'toolBarItem',
                            text: '按钮',
                            appearance: {
                                class: 'btn'
                            }
                        },
                        parentNodeId: propertyData.id,
                        getPropertyConfig: (selectedNode, triggerModalSave: any) => toolbarItemProp.getPropertyConfigInTree(viewModelId, true, selectedNode, triggerModalSave),
                        beforeSave: () => toolbarItemProp.beforeToolbarSaved(propertyData.parent && propertyData.parent.id, viewModelId)
                    },
                    visible: propertyData.modalConfig && propertyData.modalConfig.showFooterButtons
                }

            ],
            setPropertyRelates(changeObject, data, parameters) {
                if (!changeObject) {
                    return;
                }
                switch (changeObject.propertyID) {
                    case 'showHeader': {
                        this.properties.map(p => {
                            if (p.category === 'header') {
                                p.visible = changeObject.propertyValue;
                            }
                        });

                        break;
                    }
                    case 'showFooterButtons': {
                        const footerButtons = this.properties.find(p => p.propertyID === 'footerButtons');
                        if (footerButtons) {
                            footerButtons.visible = changeObject.propertyValue;
                        }
                    }
                }
            }
        }];
    }

    /**
     * 列编辑器属性
     */
    getGridFieldEdtiorPropConfig(gridFieldData: any, viewModelId: string) {
        const propertyData = gridFieldData.editor;
        this.propertyConfig = [];

        // 编辑器类型属性
        const editorTypeConfig = this.getGridFieldEditorTypePropertyConfig(gridFieldData, viewModelId);
        if (editorTypeConfig) {
            this.propertyConfig.push(editorTypeConfig);
        }

        // 弹出表单框属性
        const openModalPropConfigs = this.getOpenModalPropConfigs(propertyData, viewModelId, 'gridFieldEditor');

        // 外观属性
        const apperanceConfig = this.getAppearancePropConfig(propertyData, viewModelId, openModalPropConfigs, 'gridFieldEditor');
        this.propertyConfig.push(apperanceConfig);

        // 行为属性
        const behaviorConfig = this.getBehaviorPropConfig(propertyData, viewModelId, openModalPropConfigs, 'gridFieldEditor');
        this.appendBehaviorPropsForGridFieldEditor(behaviorConfig, propertyData, viewModelId);
        this.propertyConfig.push(behaviorConfig);

        this.propertyConfig = this.propertyConfig.concat(openModalPropConfigs);

        // 事件属性
        const eventPropConfig = this.getEventPropConfig(propertyData, viewModelId, 'gridFieldEditor');

        this.propertyConfig.push(eventPropConfig);

        return this.propertyConfig;

    }

    /**
     * table单元格编辑器属性
     * @param tdData 单元格数据
     * @param viewModelId viewModelId
     * @returns 属性配置
     */
    getTableTdEdtiorPropConfig(tdData: any, viewModelId: string): ElementPropertyConfig[] {
        const propertyData = tdData.editor;

        this.propertyConfig = [];


        // 弹出表单框属性
        const openModalPropConfigs = this.getOpenModalPropConfigs(propertyData, viewModelId, 'tableTdEditor');

        // 外观属性
        const apperanceConfig = this.getAppearancePropConfig(propertyData, viewModelId, openModalPropConfigs, 'tableTdEditor');
        this.propertyConfig.push(apperanceConfig);

        // 行为属性
        const behaviorConfig = this.getBehaviorPropConfig(propertyData, viewModelId, openModalPropConfigs, 'tableTdEditor');
        behaviorConfig.properties = behaviorConfig.properties.filter(p => !'binding,visible'.includes(p.propertyID));
        this.propertyConfig.push(behaviorConfig);

        this.propertyConfig = this.propertyConfig.concat(openModalPropConfigs);

        // 扩展区域属性
        const appendPropConfig = this.getInputAppendPropertyConfig(propertyData, viewModelId, 'tableTdEditor');
        this.propertyConfig.push(appendPropConfig);

        // 表达式属性
        const exprPropConfig = this.getExpressionPropConfig(propertyData, viewModelId, 'tableTdEditor');
        if (exprPropConfig) {
            this.propertyConfig.push(exprPropConfig);
        }

        // 事件属性
        const eventPropConfig = this.getEventPropConfig(propertyData, viewModelId, 'gridFieldEditor');
        this.propertyConfig.push(eventPropConfig);

        return this.propertyConfig;
    }

}
